/*
 * Copyright 2013-2019 Xia Jun(3979434@qq.com).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ***************************************************************************************
 *                                                                                     *
 *                        Website : http://www.farsunset.com                           *
 *                                                                                     *
 ***************************************************************************************
 */
package com.workcell.workdata.im.configuration;

import com.workcell.workdata.im.constant.Common;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;

import java.util.ArrayList;
import java.util.List;

@EnableOpenApi
@Configuration
public class SwaggerConfiguration {
    @Bean
    public Docket innerApiDocket(ApiInfo apiInfo) {
        return new Docket(DocumentationType.OAS_30)
                .apiInfo(apiInfo)
                .groupName("系统内部接口")
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.workcell.workdata.im.mvc.controller.inner"))
                .build();
    }

    @Bean
    public Docket openApiDocket(ApiInfo apiInfo) {
        return new Docket(DocumentationType.OAS_30)
                .apiInfo(apiInfo)
                .groupName("公共开放接口")
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.workcell.workdata.im.mvc.controller.open"))
                .build();
    }

    @Bean
    public Docket userApiDocket(ApiInfo apiInfo) {
        return new Docket(DocumentationType.OAS_30)
                .apiInfo(apiInfo)
                .groupName("APP接口-用户相关")
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.workcell.workdata.im.mvc.controller.user"))
                .build()
                .securitySchemes(securitySchemes())
                .securityContexts(securityContexts());
    }

    @Bean
    public Docket groupApiDocket(ApiInfo apiInfo) {
        return new Docket(DocumentationType.OAS_30)
                .apiInfo(apiInfo)
                .groupName("APP接口-群组相关")
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.workcell.workdata.im.mvc.controller.group"))
                .build()
                .securitySchemes(securitySchemes())
                .securityContexts(securityContexts());
    }

    @Bean
    public Docket messageApiDocket(ApiInfo apiInfo) {
        return new Docket(DocumentationType.OAS_30)
                .apiInfo(apiInfo)
                .groupName("APP接口-消息相关")
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.workcell.workdata.im.mvc.controller.message"))
                .build()
                .securitySchemes(securitySchemes())
                .securityContexts(securityContexts());
    }

    @Bean
    public Docket exploreApiDocket(ApiInfo apiInfo) {
        return new Docket(DocumentationType.OAS_30)
                .apiInfo(apiInfo)
                .groupName("APP接口-探索相关")
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.workcell.workdata.im.mvc.controller.explore"))
                .build()
                .securitySchemes(securitySchemes())
                .securityContexts(securityContexts());
    }

    @Bean
    public Docket momentApiDocket(ApiInfo apiInfo) {
        return new Docket(DocumentationType.OAS_30)
                .apiInfo(apiInfo)
                .groupName("APP接口-朋友圈相关")
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.workcell.workdata.im.mvc.controller.moment"))
                .build()
                .securitySchemes(securitySchemes())
                .securityContexts(securityContexts());
    }

    @Bean
    public Docket webrtcApiDocket(ApiInfo apiInfo) {
        return new Docket(DocumentationType.OAS_30)
                .apiInfo(apiInfo)
                .groupName("APP接口-通话相关")
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.workcell.workdata.im.mvc.controller.webrtc"))
                .build()
                .securitySchemes(securitySchemes())
                .securityContexts(securityContexts());
    }

    @Bean
    public Docket systemApiDocket(ApiInfo apiInfo) {
        return new Docket(DocumentationType.OAS_30)
                .apiInfo(apiInfo)
                .groupName("APP接口-系统相关")
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.workcell.workdata.im.mvc.controller.system"))
                .build()
                .securitySchemes(securitySchemes())
                .securityContexts(securityContexts());
    }

    private List<SecurityScheme> securitySchemes() {
        List<SecurityScheme> schemeList = new ArrayList<>();
        schemeList.add(new ApiKey(Common.MVC_HEADER_TOKEN, Common.MVC_HEADER_TOKEN, "header"));
        schemeList.add(new ApiKey(Common.MVC_HEADER_APP_TYPE, Common.MVC_HEADER_APP_TYPE, "header"));
        schemeList.add(new ApiKey(Common.MVC_HEADER_APP_VERSION, Common.MVC_HEADER_APP_VERSION, "header"));
        schemeList.add(new ApiKey(HttpHeaders.ACCEPT_LANGUAGE, HttpHeaders.ACCEPT_LANGUAGE, "header"));
        return schemeList;
    }

    private List<SecurityContext> securityContexts() {
        List<SecurityContext> securityContextList = new ArrayList<>();
        List<SecurityReference> securityReferenceList = new ArrayList<>();
        securityReferenceList.add(new SecurityReference(Common.MVC_HEADER_TOKEN, new AuthorizationScope[]{new AuthorizationScope("global", "accessAnything")}));
        securityReferenceList.add(new SecurityReference(Common.MVC_HEADER_APP_TYPE, new AuthorizationScope[]{new AuthorizationScope("global", "accessAnything")}));
        securityReferenceList.add(new SecurityReference(Common.MVC_HEADER_APP_VERSION, new AuthorizationScope[]{new AuthorizationScope("global", "accessAnything")}));
        securityReferenceList.add(new SecurityReference(HttpHeaders.ACCEPT_LANGUAGE, new AuthorizationScope[]{new AuthorizationScope("global", "accessAnything")}));
        securityContextList.add(SecurityContext
                .builder()
                .securityReferences(securityReferenceList)
                .operationSelector(operationContext -> true)
                .build()
        );
        return securityContextList;
    }

    @Bean
    public ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("Hoxin Boot Service APIs.")
                .description("和信业务系统接口文档")
                .version("2.0")
                .build();
    }

}
